题目描述
请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。
例如,二叉树 [1,2,2,3,4,4,3] 是对称的。
1 2 3 4 5
| 1 / \ 2 2 / \ / \ 3 4 4 3
|
但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的:
示例 1:
1 2
| 输入:root = [1,2,2,3,4,4,3] 输出:true
|
示例 2:
1 2
| 输入:root = [1,2,2,null,3,null,3] 输出:false
|
限制:
$0 <= 节点个数 <= 1000$
注意:本题与主站 101 题相同:https://leetcode-cn.com/problems/symmetric-tree/
算法 1
(BFS,递归) $O(n)$
判断一棵树是否是镜像对称的,需要递归判断左右两个子树是否是镜像对称的。
两个子树镜像对称当前仅当:
- 两个子树的根节点相等。
- 第一棵子树的左子树和第二棵子树的右子树镜像对称,且第一棵子树的右子树和第二棵子树的左子树镜像对称。
注意:
- 两个节点互为镜像的递归出口条件是两个空节点互为镜像。
- 递归函数的含义:判断两棵子树是否镜像对称
时间复杂度
每个节点从上到下最多被遍历一次,所以时间复杂度为 $O(n)$。
空间复杂度
$O(logn)$,最坏情况下二叉树层链状,空间复杂度为 $O(n)$。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
class Solution { public: bool dfs(TreeNode* p, TreeNode * q) { if (!p && !q) return true; if (!p || !q || p->val != q->val) return false; return dfs(p->left, q->right) && dfs(p->right, q->left); }
bool isSymmetric(TreeNode* root) { if (!root) return true; return dfs(root->left, root->right); } };
|
算法 2
(BFS,迭代) $O(n)$
使用队列来存储两个子树中要比较的节点,每次从队头取两个节点(左子树的左孩子和右子树的右孩子或者左子树的右孩子和右子树的左孩子)判断是否互为镜像。
其他的思路和递归是一样的。同时用栈也可以。
时间复杂度
每个节点从上到下最多被遍历一次,所以时间复杂度为 $O(n)$。
空间复杂度
$O(logn)$,最坏情况下二叉树层链状,空间复杂度为 $O(n)$。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
|
class Solution { public: bool isSymmetric(TreeNode* root) { if (!root) return true; queue<TreeNode*> q; q.push(root->left), q.push(root->right);
while (q.size()) { auto l = q.front(); q.pop(); auto r = q.front(); q.pop();
if (!l && !r) continue; if (!l || !r || l->val != r->val) return false;
q.push(l->left), q.push(r->right); q.push(l->right), q.push(r->left); }
return true; } };
|